/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 *
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 *
 * Last Modified: 2016-4-12 14:41:12
 ******************************************************************************/
package cn.com.xy.sms.sdk.ui.popu.util;

import android.annotation.SuppressLint;
import android.text.Layout;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.TextView;

public class LinkTouchMovementMethod extends LinkMovementMethod {
    private TouchableSpan mPressedSpan;
    /*SDK-605 hewengao/20161003 start*/
    private Spannable mSpannable = null;
    private static BgSpan mBgSpan = new BgSpan();
    /*SDK-605 hewengao/20161003 end*/
    private static LinkTouchMovementMethod mInstance = null;
    
    /*SDK-737 zhaojiangwei/20170321 start*/
    private static boolean mDistributeTouch = true;
    /*SDK-737 zhaojiangwei/20170321 end*/
    
    public static MovementMethod getLinkTouchInstance() {
        if (mInstance == null)
            mInstance = new LinkTouchMovementMethod();

        return mInstance;
    }
    
    /*SDK-737 zhaojiangwei/20170321 start*/
    public static MovementMethod getLinkTouchInstance(boolean distributeTouch) {
        mDistributeTouch = distributeTouch;
        if (mInstance == null)
            mInstance = new LinkTouchMovementMethod();
        return mInstance;
    }
    /*SDK-737 zhaojiangwei/20170321 end*/

    private LinkTouchMovementMethod() {
    }

    @SuppressLint("NewApi")
    @Override
    public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {
        // TODO Auto-generated method stub
        return super.onGenericMotionEvent(widget, text, event);
    }

    @Override
    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
        // TODO Auto-generated method stub
        return super.onTrackballEvent(widget, text, event);
    }

    @Override
    public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        return super.onKeyDown(widget, text, keyCode, event);
    }

    @Override
    public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) {
        return super.onKeyUp(widget, text, keyCode, event);
    }

    @Override
    public boolean onKeyOther(TextView widget, Spannable text, KeyEvent event) {
        return super.onKeyOther(widget, text, event);
    }

    @Override
    public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
        boolean isOnTouch = false;
        /*SDK-605 hewengao/20161003 start*/
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            mPressedSpan = getPressedSpan(textView, spannable, event);
            int start = spannable.getSpanStart(mPressedSpan);
            int end = spannable.getSpanEnd(mPressedSpan);
            setTextLink(spannable, start, end);
            if (mPressedSpan != null) {
                mPressedSpan.setPressed(true);
                // Selection.setSelection(spannable, start,end);
                isOnTouch = true;
            }
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event);
            if (mPressedSpan != null && touchedSpan != mPressedSpan) {
                mPressedSpan.setPressed(false);
                mPressedSpan = null;
                removeTextLink(spannable);
                // Selection.removeSelection(spannable);
                isOnTouch = true;
            } else if (mPressedSpan != null) {
                isOnTouch = true;
            }
        } else {
            removeTextLink(spannable);
            if (mPressedSpan != null) {
                mPressedSpan.setPressed(false);
                removeTextLink(spannable);
                // Selection.removeSelection(spannable);
                super.onTouchEvent(textView, spannable, event);
                isOnTouch = true;
            }
            mPressedSpan = null;
            // Selection.removeSelection(spannable);
        }
        /* SDK-580 zhaojiangwei 20160805 start */
        if (!isOnTouch && mDistributeTouch) {
            removeTextLink(spannable);
            /*SDK-605 hewengao/20161003 end*/
            //可在父view的布局文件中添加android:descendantFocusability="blocksDescendants" 
            //以避免touch事件受到小源特征值的影响
            ViewGroup group = (ViewGroup) textView.getParent();
            while (group != null) {
                isOnTouch = group.onTouchEvent(event);
                if (isOnTouch) {
                    return isOnTouch;
                }
                group = (ViewGroup) group.getParent();
            }
        }
        /* SDK-580 zhaojiangwei 20160805 end */
        return isOnTouch;
    }
    TouchableSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent event) {

        int x = (int) event.getX();
        int y = (int) event.getY();

        x -= textView.getTotalPaddingLeft();
        y -= textView.getTotalPaddingTop();

        x += textView.getScrollX();
        y += textView.getScrollY();

        Layout layout = textView.getLayout();
        int line = layout.getLineForVertical(y);
        int off = layout.getOffsetForHorizontal(line, x);

        TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class);
        TouchableSpan touchedSpan = null;
        if (link.length > 0) {
            touchedSpan = link[0];
        }
        return touchedSpan;
    }
    /*SDK-605 hewengao/20161003 start*/
    private void setTextLink(Spannable text, int spanStart, int spanEnd) {
        if (text == null || spanStart == -1 || spanEnd == -1) {
            return;
        }
        if (mBgSpan != null) {
            text.setSpan(mBgSpan, spanStart, spanEnd, 0);
        }
        mSpannable = text;
    }

    private void removeTextLink(Spannable text) {

        if (text == null) {
            return;
        }
        if (mBgSpan != null) {
            text.removeSpan(mBgSpan);
        }
        mSpannable = null;
    }
    public void clear() {
        removeTextLink(mSpannable);
        if (mPressedSpan != null) {
            mPressedSpan.setPressed(false);
            mPressedSpan = null;
        }
        mSpannable = null;
    }
    /*SDK-605 hewengao/20161003 end*/
}